package com.selen.component;

import cn.hutool.core.util.ObjectUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author Selen
 */
@Slf4j
@Aspect
@Component
public class ServiceAspect {

    @Around("execution(public * com.selen.service.impl.*.*(..))")
    @SneakyThrows
    public Object AroundAdvice(ProceedingJoinPoint point){
        // 获取方法参数
        Object[] args = point.getArgs();
        // 组装完整业务方法名：类名.方法名()
        String className = point.getTarget().toString();
        className = className.substring(className.lastIndexOf('.') + 1, className.indexOf('@'));
        String methodName = point.getSignature().getName();
        methodName = className + "." + methodName + "()";

        // 前置通知: 检查参数中是否存在空值
        if (ObjectUtil.hasNull(args)){
            String msg = "业务方法" + className + "." + methodName + "()中存在null值参数";
            throw new RuntimeException(msg);

        }
        // 调用目标方法
        Object returnValue = point.proceed(args);
        // 后置通知: 记录业务层调用日志
        System.out.printf("通知: 业务方法 %s 被调用:\n\t形参：%s\n\t返回：%s\n",
                methodName, Arrays.toString(args), returnValue);

        return  returnValue;
    }

}
